#include "ramfs.h"

// 自定义字符串比较函数
int my_strcmp(const char *s1, const char *s2) {
    while (*s1 && *s2 && *s1 == *s2) {
        s1++;
        s2++;
    }
    return *s1 - *s2;
}

// 自定义字符串复制函数
void my_strcpy(char *dest, const char *src) {
    while (*src) {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
}

// 自定义内存复制函数
void my_memcpy(void *dest, const void *src, size_t n) {
    char *d = (char *)dest;
    const char *s = (const char *)src;
    while (n--) {
        *d++ = *s++;
    }
}

// ramfs 文件系统
FS ramfs_fs;

// 查找节点
VFSNode* ramfs_find_node(VFSNode *parent, const char *name) {
    VFSNode *current = parent ? parent->dir.children : ramfs_fs.root->dir.children;
    while (current != NULL) {
        if (my_strcmp(current->name, name) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// ramfs 创建节点
VFSNode* ramfs_creat(VFSNode *parent, const char *name, mode_t mode, FileType type) {
    VFSNode *new_node = (VFSNode*)kmalloc(sizeof(VFSNode), 0);
    if (new_node == NULL) {
        return NULL;
    }
    my_strcpy(new_node->name, name);
    new_node->type = type;
    if (type == FILE_TYPE_FILE) {
        new_node->file.data = NULL;
        new_node->file.size = 0;
    } else {
        new_node->dir.children = NULL;
    }
    new_node->next = parent ? parent->dir.children : ramfs_fs.root->dir.children;
    if (parent) {
        parent->dir.children = new_node;
    } else {
        ramfs_fs.root->dir.children = new_node;
    }
    return new_node;
}

// ramfs 读取文件
ssize_t ramfs_read(VFSNode *node, void *buf, size_t count) {
    if (node->type != FILE_TYPE_FILE) {
        return VFS_EPERM;
    }
    size_t read_size = (node->file.size < count) ? node->file.size : count;
    my_memcpy(buf, node->file.data, read_size);
    return read_size;
}

// ramfs 写入文件
ssize_t ramfs_write(VFSNode *node, const void *buf, size_t count) {
    if (node->type != FILE_TYPE_FILE) {
        return VFS_EPERM;
    }
    // 不使用 realloc，直接释放旧内存再分配新内存
    if (node->file.data) {
        kfree(node->file.data);
    }
    node->file.data = (char*)kmalloc(count, 0);
    if (node->file.data == NULL) {
        return VFS_EIO;
    }
    my_memcpy(node->file.data, buf, count);
    node->file.size = count;
    return count;
}

// ramfs 删除节点
int ramfs_del(VFSNode *parent, const char *name) {
    VFSNode *current = parent ? parent->dir.children : ramfs_fs.root->dir.children;
    VFSNode *previous = NULL;

    while (current != NULL && my_strcmp(current->name, name) != 0) {
        previous = current;
        current = current->next;
    }

    if (current == NULL) {
        return VFS_ENOENT;
    }

    if (previous == NULL) {
        if (parent) {
            parent->dir.children = current->next;
        } else {
            ramfs_fs.root->dir.children = current->next;
        }
    } else {
        previous->next = current->next;
    }

    if (current->type == FILE_TYPE_FILE) {
        kfree(current->file.data);
    }
    kfree(current);
    return 0;
}

// ramfs 创建链接（暂不实现）
int ramfs_link(VFSNode *old_parent, const char *old_name, VFSNode *new_parent, const char *new_name) {
    return VFS_EPERM;
}

// ramfs 创建目录
int ramfs_mkdir(VFSNode *parent, const char *name, mode_t mode) {
    VFSNode *new_dir = ramfs_creat(parent, name, mode, FILE_TYPE_DIR);
    if (new_dir == NULL) {
        return VFS_EIO;
    }
    return 0;
}

// ramfs 删除目录
int ramfs_rmdir(VFSNode *parent, const char *name) {
    VFSNode *dir = ramfs_find_node(parent, name);
    if (dir == NULL) {
        return VFS_ENOENT;
    }
    if (dir->dir.children != NULL) {
        return VFS_EPERM; // 非空目录不能删除
    }
    return ramfs_del(parent, name);
}

// ramfs 读取目录（暂不实现）
int ramfs_readdir(VFSNode *node, void *buf, size_t count) {
    return VFS_EPERM;
}

// ramfs 操作集合
FSOP ramfs_op = {
    .read = ramfs_read,
    .write = ramfs_write,
    .del = ramfs_del,
    .creat = ramfs_creat,
    .link = ramfs_link,
    .mkdir = ramfs_mkdir,
    .rmdir = ramfs_rmdir,
    .readdir = ramfs_readdir
};

// 初始化 ramfs
void ramfs_init() {
    ramfs_fs.root = (VFSNode*)kmalloc(sizeof(VFSNode), 0);
    if (ramfs_fs.root == NULL) {
        return;
    }
    my_strcpy(ramfs_fs.root->name, "/");
    ramfs_fs.root->type = FILE_TYPE_DIR;
    ramfs_fs.root->dir.children = NULL;
    ramfs_fs.root->next = NULL;
    my_strcpy(ramfs_fs.name, "ramfs");
    ramfs_fs.op = ramfs_op;
}